package org.vacoor.nothing.ui.hotkey.impl.win;

import com.melloware.jintellitype.JIntellitype;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.vacoor.nothing.common.misc.util.Platform;
import org.vacoor.nothing.common.misc.util.Resources;
import org.vacoor.nothing.ui.hotkey.OSHotKeyBinder;
import org.vacoor.nothing.ui.hotkey.OSHotKeyManager;

import java.util.concurrent.ConcurrentHashMap;

/**
 * Windows 系统热键
 * <p/>
 * JIntellitype
 * http://code.google.com/p/jintellitype/
 * <p/>
 * User: Vacoor
 */
public class JIntellitypeManager extends OSHotKeyManager {
    private static final Logger logger = LoggerFactory.getLogger(org.vacoor.nothing.ui.hotkey.impl.win.JIntellitypeManager.class);
    private static final String WIN_64_LIB = "native_lib/JIntellitype_x64.dll";
    private static final String WIN_32_LIB = "native_lib/JIntellitype_x32.dll";
    private static final String EXTRACT_FILE = System.getProperty("java.io.tmpdir") + "/" + Platform.getResourcePrefix() + "-hotkey.dll";

    private static ConcurrentHashMap<Integer, OSHotKeyBinder> binders = new ConcurrentHashMap<Integer, OSHotKeyBinder>();
    private static JIntellitype jIntellitype;
    private static boolean initialzed;

    private static void init() {
        if (!initialzed && Platform.isWindows()) {
            try {
                String lib = !Platform.is64Bit() ? WIN_32_LIB : WIN_64_LIB;
                lib = Resources.extractResourceAsCanonicalPath(lib, EXTRACT_FILE);
                JIntellitype.setLibraryLocation(lib);
                jIntellitype = JIntellitype.getInstance();
            } catch (Throwable t) {
                logger.warn("JIntellitype init fail", t);
            }
        }
        initialzed = true;
    }

    @Override
    public boolean supportCurrentOS() {
        if (!initialzed) {
            init();
        }
        return jIntellitype != null;
    }

    @Override
    public OSHotKeyBinder getOSHotKeyBinder(final int identifier) {
        if (!supportCurrentOS()) {
            return null;
        }

        // 低32位为key, 高32位为 mask
        //  final long hotKey = ((awtModifiers + 0L) << 8 * 4) + awtKey;
        OSHotKeyBinder binder = binders.get(identifier);
        if (binder != null) {
            return binder;
        }
        synchronized (binders) {
            if (binder == null) {
                binder = new JIntellitypeKeyBinder(jIntellitype, identifier);
                binders.put(identifier, binder);
            }
        }
        return binder;
    }

    @Override
    public void destory() {
        if (jIntellitype != null) {
            /*
            for(int i : binders.keySet()) {
                jIntellitype.unregisterHotKey(i);
            }
            */
            jIntellitype.cleanUp();
        }
    }
}
